   /*
 * RTCC1.c
 *
 *  Created on: 19/12/2012
 *      Author: RIchard
 */

#include <string.h>

#include <msp430.h>
#include "RTCC1.h"
#include "../../sensor.h"
#include "../../Application/SENSORS/SNSR/SNSRC1.h"

static void (*RTC_pfGetRTCCallback)(RTC_tstTime *stTime);

static inline void RTC__vGetTime( RTC_tstTime * stTime );

void RTC_vReset( void )
{
   static const RTC_tstDate RTC__cstDate =
   {
      0x01,
      0x03,
      0x03,
      0x2013
   };

   static const RTC_tstTime RTC__cstTime =
   {
      0x00,
      0x30,
      0x20
   };

   RTC_pfGetRTCCallback = NULL;

   RTCCTL01 = RTCMODE + RTCHOLD + RTCBCD + RTCTEVIE;

   RTC_vSetCalendarEvent( RTC_nCalendarEvent_MinuteChange );
   RTC_vSetTime( &RTC__cstTime );
   RTC_vSetDate( &RTC__cstDate );

   RTCCTL1 &= ~( RTCHOLD_H );
}

void RTC_vSetTime( RTC_tstTime const * stTime )
{
   bool boTemp;

   boTemp = ( ( RTCCTL1 & RTCHOLD_H ) == RTCHOLD_H );
   RTCCTL1 |= RTCHOLD_H;

   RTCSEC = stTime->u8Seconds;
   RTCMIN = stTime->u8Minutes;
   RTCHOUR = stTime->u8Hours;

   if( boTemp == 0 )
   {
      RTCCTL1 &= ~( RTCHOLD_H );
   }
}

void RTC_vSetDate( RTC_tstDate const * stDate )
{
   bool boTemp;

   boTemp = ( ( RTCCTL1 & RTCHOLD_H ) == RTCHOLD_H );
   RTCCTL1 |= RTCHOLD_H;

   RTCDOW = stDate->u8DayOfWeek;
   RTCDAY = stDate->u8DayOfMonth;
   RTCMON = stDate->u8Month;
   RTCYEAR = stDate->u16Year;

   if( boTemp == 0 )
   {
      RTCCTL1 &= ~( RTCHOLD_H );
   }
}

void RTC_vGetTime( void (*pfGetRTCCallback)(RTC_tstTime *stTime) )
{
   /* Store callback function */
   RTC_pfGetRTCCallback = pfGetRTCCallback;

   /* Set RDY interrupt */
   RTCCTL0 &= ~( RTCRDYIFG_L );
   RTCCTL0 |= RTCRDYIE_L;
}

void RTC_vSetCalendarEvent( RTC_tenCalendarEvent enCalendarEvent )
{
   /* Clear any previous time events */
   RTCCTL1 &= ~( RTCTEV0_H + RTCTEV1_H );

   /* Set new event */
   RTCCTL1 |= (uint8)enCalendarEvent;
}

static inline void RTC__vGetTime( RTC_tstTime * stTime )
{
   stTime->u8Seconds = RTCSEC;
   stTime->u8Minutes = RTCMIN;
   stTime->u8Hours = RTCHOUR;
}


#pragma vector=RTC_VECTOR
__interrupt void RTC_vISR( void )
{
   RTC_tstTime stTime;

   switch( __even_in_range( RTCIV, 0x0E ) )
   {
      case RTCIV_RTCRDYIFG:
         /* Run get date/time application callback */
         if( RTC_pfGetRTCCallback != NULL )
         {
            /* Disable the interrupt */
            RTCCTL0 &= ~( RTCRDYIE_L );
            /* Get the time from the RTC registers */
            RTC__vGetTime( &stTime );
            /* Pass the data back to the application */
            RTC_pfGetRTCCallback( &stTime );
         }
         break;
      case RTCIV_RTCTEVIFG:
         APP_unRequests.F.biProcessSensorPeriod = 1;
         /* wake up */
         _BIC_SR_IRQ(LPM3_bits);
         break;
      default:
         _never_executed();
         break;
   }
}
